diff --git a/cpu/ixp/npe/IxNpeDlImageMgr.c b/cpu/ixp/npe/IxNpeDlImageMgr.c
new file mode 100644
index 0000000..e05c228
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeDlImageMgr.c
@@ -0,0 +1,675 @@
+/**
+ * @file IxNpeDlImageMgr.c
+ *
+ * @author Intel Corporation
+ * @date 09 January 2002
+ *
+ * @brief This file contains the implementation of the private API for the 
+ *        IXP425 NPE Downloader ImageMgr module
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/*
+ * Put the system defined include files required.
+ */
+#include "IxOsal.h"
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDlImageMgr_p.h"
+#include "IxNpeDlMacros_p.h"
+
+/*
+ * define the flag which toggles the firmare inclusion
+ */
+#define IX_NPE_MICROCODE_FIRMWARE_INCLUDED 1
+#include "IxNpeMicrocode.h"
+
+/*
+ * Indicates the start of an NPE Image, in new NPE Image Library format.
+ * 2 consecutive occurances indicates the end of the NPE Image Library
+ */
+#define NPE_IMAGE_MARKER 0xfeedf00d
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef struct
+{
+    UINT32 size;
+    UINT32 offset;
+    UINT32 id;
+} IxNpeDlImageMgrImageEntry;
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef union
+{
+    IxNpeDlImageMgrImageEntry image;
+    UINT32 eohMarker;
+} IxNpeDlImageMgrHeaderEntry;
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef struct
+{
+    UINT32 signature;
+    /* 1st entry in the header (there may be more than one) */
+    IxNpeDlImageMgrHeaderEntry entry[1];
+} IxNpeDlImageMgrImageLibraryHeader;
+
+
+/*
+ * NPE Image Header definition, used in new NPE Image Library format
+ */
+typedef struct
+{
+    UINT32 marker;
+    UINT32 id;
+    UINT32 size;
+} IxNpeDlImageMgrImageHeader;
+
+/* module statistics counters */
+typedef struct
+{
+    UINT32 invalidSignature;
+    UINT32 imageIdListOverflow;
+    UINT32 imageIdNotFound;
+} IxNpeDlImageMgrStats;
+
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+static IxNpeDlImageMgrStats ixNpeDlImageMgrStats;
+
+/* default image */
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+static UINT32 *IxNpeMicroCodeImageLibrary = NULL;  /* Gets set to proper value at runtime */
+#else
+static UINT32 *IxNpeMicroCodeImageLibrary = (UINT32 *)IxNpeMicrocode_array;
+#endif
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary);
+
+PRIVATE void  
+ixNpeDlImageMgrImageIdFormat (UINT32 rawImageId, IxNpeDlImageId *imageId);
+
+PRIVATE BOOL
+ixNpeDlImageMgrImageIdCompare (IxNpeDlImageId *imageIdA, 
+				 IxNpeDlImageId *imageIdB);
+				 
+PRIVATE BOOL
+ixNpeDlImageMgrNpeFunctionIdCompare (IxNpeDlImageId *imageIdA,
+    				       IxNpeDlImageId *imageIdB);
+
+PRIVATE IX_STATUS
+ixNpeDlImageMgrImageFind_legacy (UINT32 *imageLibrary,
+                                 UINT32 imageId,
+                                 UINT32 **imagePtr,
+                                 UINT32 *imageSize);
+
+/*
+ * Function definition: ixNpeDlImageMgrMicrocodeImageLibraryOverride
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrMicrocodeImageLibraryOverride (
+    UINT32 *clientImageLibrary)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlImageMgrMicrocodeImageLibraryOverride\n");
+
+    if (ixNpeDlImageMgrSignatureCheck (clientImageLibrary))
+    {
+	IxNpeMicroCodeImageLibrary = clientImageLibrary;
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrMicrocodeImageLibraryOverride: "
+			       "Client-supplied image has invalid signature\n");
+	status = IX_FAIL;
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Exiting ixNpeDlImageMgrMicrocodeImageLibraryOverride: status = %d\n",
+		     status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageListExtract
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrImageListExtract (
+    IxNpeDlImageId *imageListPtr,
+    UINT32 *numImages)
+{
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    IX_STATUS status = IX_SUCCESS;
+    UINT32 imageCount = 0;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlImageMgrImageListExtract\n");
+
+    header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+
+    if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+    {
+	/* for each image entry in the image header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    /*
+	     * if the image list container from calling function has capacity,
+	     * add the image id to the list 
+	     */
+	    if ((imageListPtr != NULL) && (imageCount < *numImages))
+	    {
+		rawImageId = header->entry[imageCount].image.id;
+	        ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+		imageListPtr[imageCount] = formattedImageId;
+	    }
+	    /* imageCount reflects no. of image entries in image library header */
+	    imageCount++;  
+	}
+	
+	/*
+	 * if image list container from calling function was too small to
+	 * contain all image ids in the header, set return status to FAIL
+	 */
+	if ((imageListPtr != NULL) && (imageCount > *numImages))
+	{
+	    status = IX_FAIL;
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
+				   "number of Ids found exceeds list capacity\n");
+	    ixNpeDlImageMgrStats.imageIdListOverflow++;
+	}
+	/* return number of image ids found in image library header */
+	*numImages = imageCount;  
+    }
+    else
+    {
+	status = IX_FAIL;
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
+			       "invalid signature in image\n");
+    }
+    
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Exiting ixNpeDlImageMgrImageListExtract: status = %d\n",
+		     status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageLocate
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrImageLocate (
+    IxNpeDlImageId *imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    UINT32 imageOffset;
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    /* used to index image entries in image library header */
+    UINT32 imageCount = 0;   
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrImageLocate\n");
+
+    header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+
+    if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+    {
+	/* for each image entry in the image library header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    rawImageId = header->entry[imageCount].image.id;
+	    ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+	    /* if a match for imageId is found in the image library header... */
+	    if (ixNpeDlImageMgrImageIdCompare (imageId, &formattedImageId))
+	    {
+		/*
+		 * get pointer to the image in the image library using offset from
+		 * 1st word in image library
+		 */
+		imageOffset = header->entry[imageCount].image.offset;
+		*imagePtr = &IxNpeMicroCodeImageLibrary[imageOffset];
+		/* get the image size */
+		*imageSize = header->entry[imageCount].image.size;
+		status = IX_SUCCESS;
+		break;
+	    }
+	    imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrImageLocate: status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrLatestImageExtract
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
+{
+    UINT32 imageCount = 0; 
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+    
+    
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrLatestImageExtract\n");
+		     
+    header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+    
+    if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+    {
+	/* for each image entry in the image library header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    rawImageId = header->entry[imageCount].image.id;
+	    ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+	    /* 
+	     * if a match for the npe Id and functionality Id of the imageId is
+	     *  found in the image library header... 
+	     */
+            if(ixNpeDlImageMgrNpeFunctionIdCompare(imageId, &formattedImageId))
+            {
+                if(imageId->major <= formattedImageId.major)
+                {
+                    if(imageId->minor < formattedImageId.minor)
+                    {
+                        imageId->minor = formattedImageId.minor;
+                    }
+                    imageId->major = formattedImageId.major;
+                }
+                status = IX_SUCCESS;
+            }
+            imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageExtract: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageGet: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrLatestImageGet: status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrSignatureCheck
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary)
+{
+    IxNpeDlImageMgrImageLibraryHeader *header =
+	(IxNpeDlImageMgrImageLibraryHeader *) microCodeImageLibrary;
+    BOOL result = TRUE;
+
+    if (header->signature != IX_NPEDL_IMAGEMGR_SIGNATURE)
+    {
+	result = FALSE;
+	ixNpeDlImageMgrStats.invalidSignature++;
+    }
+
+    return result;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageIdFormat
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE void
+ixNpeDlImageMgrImageIdFormat (
+    UINT32 rawImageId, 
+    IxNpeDlImageId *imageId)
+{  
+    imageId->npeId = (rawImageId >>
+				IX_NPEDL_IMAGEID_NPEID_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->functionalityId = (rawImageId >> 
+				  IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->major = (rawImageId >>
+				IX_NPEDL_IMAGEID_MAJOR_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->minor = (rawImageId >>
+				IX_NPEDL_IMAGEID_MINOR_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageIdCompare
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrImageIdCompare (
+    IxNpeDlImageId *imageIdA,
+    IxNpeDlImageId *imageIdB)
+{
+    if ((imageIdA->npeId   == imageIdB->npeId)   &&
+	(imageIdA->functionalityId == imageIdB->functionalityId) &&
+	(imageIdA->major   == imageIdB->major)   &&
+	(imageIdA->minor   == imageIdB->minor))
+    {
+	return TRUE;
+    }
+    else
+    {
+	return FALSE;
+    }
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrNpeFunctionIdCompare
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrNpeFunctionIdCompare (
+    IxNpeDlImageId *imageIdA,
+    IxNpeDlImageId *imageIdB)
+{
+    if ((imageIdA->npeId   == imageIdB->npeId)   &&
+	(imageIdA->functionalityId == imageIdB->functionalityId))
+    {
+	return TRUE;
+    }
+    else
+    {
+	return FALSE;
+    }
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrStatsShow
+ */
+void
+ixNpeDlImageMgrStatsShow (void)
+{
+    ixOsalLog (IX_OSAL_LOG_LVL_USER,
+               IX_OSAL_LOG_DEV_STDOUT,
+               "\nixNpeDlImageMgrStatsShow:\n"
+               "\tInvalid Image Signatures: %u\n"
+               "\tImage Id List capacity too small: %u\n"
+               "\tImage Id not found: %u\n\n",
+               ixNpeDlImageMgrStats.invalidSignature,
+               ixNpeDlImageMgrStats.imageIdListOverflow,
+               ixNpeDlImageMgrStats.imageIdNotFound,
+               0,0,0);
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrStatsReset
+ */
+void
+ixNpeDlImageMgrStatsReset (void)
+{
+    ixNpeDlImageMgrStats.invalidSignature = 0;
+    ixNpeDlImageMgrStats.imageIdListOverflow = 0;
+    ixNpeDlImageMgrStats.imageIdNotFound = 0;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageFind_legacy
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE IX_STATUS
+ixNpeDlImageMgrImageFind_legacy (
+    UINT32 *imageLibrary,
+    UINT32 imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    UINT32 imageOffset;
+    /* used to index image entries in image library header */
+    UINT32 imageCount = 0;   
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+    BOOL imageFound = FALSE;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrImageFind\n");
+
+
+    /* If user didn't specify a library to use, use the default
+     * one from IxNpeMicrocode.h
+     */
+    if (imageLibrary == NULL)
+    {
+	imageLibrary = IxNpeMicroCodeImageLibrary;
+    }
+    
+    if (ixNpeDlImageMgrSignatureCheck (imageLibrary))
+    {
+	header = (IxNpeDlImageMgrImageLibraryHeader *) imageLibrary;
+    
+	/* for each image entry in the image library header ... */
+	while ((header->entry[imageCount].eohMarker !=
+               IX_NPEDL_IMAGEMGR_END_OF_HEADER) && !(imageFound))
+	{
+	    /* if a match for imageId is found in the image library header... */
+	    if (imageId == header->entry[imageCount].image.id)
+	    {
+		/*
+		 * get pointer to the image in the image library using offset from
+		 * 1st word in image library
+		 */
+		imageOffset = header->entry[imageCount].image.offset;
+		*imagePtr = &imageLibrary[imageOffset];
+		/* get the image size */
+		*imageSize = header->entry[imageCount].image.size;
+		status = IX_SUCCESS;
+		imageFound = TRUE;
+	    }
+	    imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrImageFind: status = %d\n", status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageFind
+ */
+IX_STATUS
+ixNpeDlImageMgrImageFind (
+    UINT32 *imageLibrary,
+    UINT32 imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    IxNpeDlImageMgrImageHeader *image;
+    UINT32 offset = 0;
+
+    /* If user didn't specify a library to use, use the default
+     * one from IxNpeMicrocode.h
+     */
+    if (imageLibrary == NULL)
+    {
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+	if (ixNpeMicrocode_binaryArray == NULL)
+        {
+	    printk (KERN_ERR "ixp400.o:  ERROR, no Microcode found in memory\n");
+	    return IX_FAIL;
+	}
+	else
+	{
+	    imageLibrary = ixNpeMicrocode_binaryArray;
+	}
+#else
+	imageLibrary = IxNpeMicroCodeImageLibrary;
+#endif /* IX_NPEDL_READ_MICROCODE_FROM_FILE */
+    }
+
+    /* For backward's compatibility with previous image format */
+    if (ixNpeDlImageMgrSignatureCheck(imageLibrary))
+    {
+        return ixNpeDlImageMgrImageFind_legacy(imageLibrary,
+                                               imageId,
+                                               imagePtr,
+                                               imageSize);
+    }
+
+    while (*(imageLibrary+offset) == NPE_IMAGE_MARKER)
+    {
+        image = (IxNpeDlImageMgrImageHeader *)(imageLibrary+offset);
+        offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(UINT32);
+        
+        if (image->id == imageId)
+        {
+            *imagePtr = imageLibrary + offset;
+            *imageSize = image->size;
+            return IX_SUCCESS;
+        }
+        /* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */
+        else if (image->id == NPE_IMAGE_MARKER)
+        {
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+            /* reached end of library, image not found */
+            return IX_FAIL;
+        }
+        offset += image->size;
+    }
+
+    /* If we get here, our image library may be corrupted */
+    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+                           "image library format may be invalid or corrupted\n");
+    return IX_FAIL;
+}
+
